package com.cskaoyan.mall.service.admin;

import com.cskaoyan.mall.dao.admin.GoodsDao;
import com.cskaoyan.mall.dao.admin.GoodsDaoImpl;
import com.cskaoyan.mall.model.Goods;
import com.cskaoyan.mall.model.Type;
import com.cskaoyan.mall.model.bo.admin.*;
import com.cskaoyan.mall.model.vo.admin.MsgReplyVO;
import com.cskaoyan.mall.model.vo.admin.MsgVO;

import java.util.List;
import java.util.Map;

public class GoodsServiceImpl implements GoodsService{
    private GoodsDao goodsDao = new GoodsDaoImpl();
    @Override
    public List<Type> getType() {
        return goodsDao.getType();
    }

    @Override
    public List<Goods> getGoodsByType(String typeId) {
        return goodsDao.getGoodsByType(typeId);
    }

    /**
     * 在该层需要做的事务有点多
     * 1、对应的信息保存到goods表，还要处理price stockNum
     * 2、将spec信息全部保存到spec表 goodsId
     * 3、必须是两者全部成功或者失败
     * 最理想的状态，无论是否开启事务，编写的代码都能够应对
     * @param addGoodsBO
     */
    @Override
    public void addGoods(AddGoodsBO addGoodsBO) {
        //从前端传来的商品信息中获取规格信息
        List<AddSpecBO> specList = addGoodsBO.getSpecList();
        //这里的price指的是所有规格中price的最小值
        double price = Double.MAX_VALUE;
        //stockNum取得是所有规格spec中的最大值
        int stockNum = 0;
        for (AddSpecBO addSpecBO : specList) {
            if (price > Double.parseDouble(addSpecBO.getUnitPrice())) {
                price = Double.parseDouble(addSpecBO.getUnitPrice());
            }
            if (stockNum < Integer.parseInt(addSpecBO.getStockNum())) {
                stockNum = Integer.parseInt(addSpecBO.getStockNum());
            }
        }
        //将goods封装的更多的数据，这样在查询的时候能够更加方便
        Goods goods = new Goods(null,addGoodsBO.getName(),addGoodsBO.getImg(),Integer.parseInt(addGoodsBO.getTypeId()), price, stockNum,addGoodsBO.getDesc());
        /*
        在goods表中插入之后，会生成一个自增的id值，这个id值需要在规格中使用到
        可以通过select last_insert_id
        即使是其他线程访问该数据库，然后插入数据，那么拿到的仍旧是你插入时的id
        线程隔离，只会取到当前线程最后一次插入的id
         */
        goodsDao.addGoods(goods);
        int goodsId = goodsDao.getLastId();
        //对应该类型的规格类型
        goodsDao.addSpecs(specList,goodsId);
    }

    @Override
    public int addType(AddTypeBO addTypeBO) {
        return goodsDao.addType(addTypeBO);
    }

    @Override
    public int deleteType(String typeId) {
        return goodsDao.deleteType(typeId);
    }

    @Override
    public Map<String, Object> getGoodsInfo(String id) {
        return goodsDao.getGoodsInfo(id);
    }

    @Override
    public int addSpec(AddSpecsBO addSpecsBO) {
        return goodsDao.addSpec(addSpecsBO);
    }

    @Override
    public int updateGoods(UpdateGoodsBO updateGoodsBO) {
        //从前端传来的商品信息中获取规格信息
        List<UpdateSpecBO> specList = updateGoodsBO.getSpecList();
        //这里的price指的是所有规格中price的最小值
        double price = Double.MAX_VALUE;
        //stockNum取得是所有规格spec中的最大值
        int stockNum = 0;
        for (UpdateSpecBO updateSpecBO : specList) {
            if (price > updateSpecBO.getUnitPrice()) {
                price = updateSpecBO.getUnitPrice();
            }
            if (stockNum < updateSpecBO.getStockNum()) {
                stockNum = updateSpecBO.getStockNum();
            }
        }
        //将goods封装的更多的数据，这样在查询的时候能够更加方便
        Goods goods = new Goods(Integer.parseInt(updateGoodsBO.getId()),updateGoodsBO.getName(),updateGoodsBO.getImg(),updateGoodsBO.getTypeId(), price, stockNum,updateGoodsBO.getDesc());
        /*
        在goods表中插入之后，会生成一个自增的id值，这个id值需要在规格中使用到
        可以通过select last_insert_id
        即使是其他线程访问该数据库，然后插入数据，那么拿到的仍旧是你插入时的id
        线程隔离，只会取到当前线程最后一次插入的id
         */
        int code1 = goodsDao.updateGoods(goods);
        //对应该类型的规格类型
        int code2 = goodsDao.updateSpecs(specList,goods.getId());
        if (code1 == 200 && code2 == 200) {
            return 200;
        }
        return 404;
    }

    @Override
    public int deleteSpec(DeleteSpecBO deleteSpecBO) {
        return goodsDao.deleteSpec(deleteSpecBO);
    }

    @Override
    public int deleteGoods(String id) {
        return goodsDao.deleteGoods(id);
    }

    @Override
    public List<MsgVO> noReplyMsg() {
        return goodsDao.noReplyMsg();
    }

    @Override
    public List<MsgReplyVO> repliedMsg() {
        return goodsDao.repliedMsg();
    }

    @Override
    public int reply(ReplyBO replyBO) {
        return goodsDao.reply(replyBO);
    }
}
